home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************************************
- *
- *
- * ObjectMacZapp -- a standard Mac OOP application template
- *
- *
- *
- * ZDialog.cpp -- a dialog box
- *
- *
- *
- *
- *
- * © 1996, Graham Cox
- *
- *
- *
- *
- *************************************************************************************************/
-
-
- #include "ZDialog.h"
- #include "MacZoop.h"
- #include "ZGrafState.h"
-
- #include <dialogs.h>
- #include <palettes.h>
- #include <fp.h>
-
- // static method and global UPP to handle user items in dialogs in a general
- // object-oriented fashion. Hey- cool feature!
-
- static pascal void UserItemVectorProc(DialogPtr theDialog, short item);
- UserItemUPP gUIVectorUPP = NewUserItemProc(UserItemVectorProc);
-
- /*-------------------------------*** CONSTRUCTOR ***----------------------------------*/
-
-
- ZDialog::ZDialog(ZCommander* aBoss, const short dialogID)
- : ZWindow(aBoss, dialogID)
- {
- isModal = FALSE; // set up by MakeMacWindow
- FailNIL( rGroupList = ( RGroupHdl ) NewHandle( 0 )); // resized as needed
- ictb = NULL;
- signalDismiss = 0;
- }
-
-
- /*---------------------------------*** DESTRUCTOR ***----------------------------------*/
-
-
- ZDialog::~ZDialog()
- {
- if ( isModal )
- gWindowManager->Activate();
-
- if ( macWindow )
- DisposeDialog( macWindow );
-
- macWindow = NULL;
-
- if ( rGroupList )
- DisposeHandle(( Handle ) rGroupList );
-
- if ( ictb )
- DisposeHandle((Handle) ictb );
- }
-
- /*-------------------------------*** INITZWINDOW ***----------------------------------*/
- /*
-
- construct the dialog and set it up
-
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::InitZWindow()
- {
- MakeMacWindow( windID ); // make the dialog box, and set modal flag
-
- SetUpUserItems(); // install user item procs so we get callbacks
- SetUpRadioGroups(); // automatically deal with radio button groups
- SetUp(); // call user's set up method
-
- // tell the window manager of our existence. This must be done after the
- // full build of the mac window since the window manager needs to get
- // information from it. Thus if you override this method, make sure you
- // make the same call.
-
- gWindowManager->AddWindow( this );
- }
-
-
- /*------------------------------*** MAKEMACWINDOW ***---------------------------------*/
- /*
-
- make a dialog. This tries to construct a dialog using a 'DLOG' resource with the ID
- passed. The refcon is set to this object, so do not use it. Sets the modal flag too.
-
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::MakeMacWindow( const short dialogID )
- {
- FailNIL( macWindow = GetNewDialog( dialogID, NULL, NULL ));
-
- // set our refcon to point to the object. DO NOT USE THE REFCON!
-
- SetWRefCon( macWindow, (long) this );
-
- // see whether this is modal or not by examining the style of the window. This
- // flag affects the way commands are processed.
-
- short wVar = GetWVariant( macWindow );
-
- isModal = ( wVar == dBoxProc ||
- wVar == plainDBox ||
- wVar == altDBoxProc ||
- wVar == movableDBoxProc );
-
- // note that dialogs should normally not set the <isFloating> member, since the window
- // manager knows that dialogs should go in front of floaters anyway. If you use a dialog as
- // a floating window, note that it won't get the menubar and keyboard focus, so you should
- // avoid the use of editable text fields, etc. Though no-one's enforcing any of this, it
- // is bad human interface to have type-in fields in floating windows.
-
- // look for any associated 'ictb' resource and keep a local copy
-
- ictb = ( ictbHandle ) GetResource( 'ictb', dialogID );
-
- if ( ictb )
- {
- DetachResource((Handle) ictb );
- HNoPurge((Handle) ictb );
- }
- }
-
-
- /*-----------------------------*** SETUPUSERITEMS ***---------------------------------*/
- /*
-
- make every user item point to our vector proc for handling these items. Then you can
- simply override DrawUserItem to draw anything you want in the dialog!
-
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::SetUpUserItems()
- {
- short item, itemType;
- Handle itemHand;
- Rect itemBox;
-
- item = CountDITL( macWindow );
-
- while( item )
- {
- GetDialogItem( macWindow, item--, &itemType, &itemHand, &itemBox );
-
- if (( itemType & 0x7F ) == userItem )
- SetDialogItem( macWindow, item + 1, itemType, (Handle) gUIVectorUPP, &itemBox );
- }
- }
-
-
-
- /*-----------------------------------*** DRAW ***-------------------------------------*/
- /*
- draws the dialog items
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::Draw()
- {
- UpdateDialog( macWindow, macWindow->visRgn );
-
- if ( isModal )
- OutlineDefaultItem();
-
- #ifdef _GREYSCALE_APPEARANCE
-
- AddGreyscaleEffects();
-
-
- #endif
- }
-
-
- /*-----------------------------------*** CLICK ***------------------------------------*/
- /*
- handle clicks in the dialog, This determines the item and calls ClickItem.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::Click( const Point mouse, const short modifiers )
- {
- DialogPeek dp = ( DialogPeek ) macWindow;
-
- // which item was hit?
-
- short item = FindDialogItem( macWindow, mouse ) + 1;
-
- // if the item is enabled, call TrackControl, TEClick, etc as needed.
-
- if ( item > 0 )
- {
- short iType, partCode;
- Handle iHand;
- Rect iBox;
-
- GetDialogItem( macWindow, item, &iType, &iHand, &iBox );
-
- // if the item is a control, track it. Call ClickItem if control clicked and
- // item was enabled and not unhilited.
-
- if (iType & ctrlItem )
- {
- if ((*(ControlHandle) iHand )->contrlHilite != 255 )
- {
- partCode = TrackControl((ControlHandle) iHand, mouse, ( ControlActionUPP ) -1L );
-
- if (( partCode != 0 ) && (( iType & 0x80 ) == 0 ))
- ClickItem( item );
- }
- }
- else
- {
- if ( iType & editText )
- {
- // if an edit field, pass click to text edit. If not in the current
- // field, switch fields to the one clicked.
-
- ZGrafState zg;
-
- if ( item != dp->editField + 1)
- SelectDialogItemText( macWindow, item, 0, 0 );
-
- SetTEItemDataFromIctb( item, TRUE );
- TEClick( mouse, (modifiers & shiftKey) == shiftKey , dp->textH );
- }
-
- // all enabled items are passed to ClickItem
-
- if (( iType & 0x80 ) == 0 )
- ClickItem( item );
- }
- }
-
- // see if any user action resulted in a request to dismiss the dialog. This is quite common-
- // e.g. a double-click in a list, etc. To close safely, we need to action this right at the end
- // of processing a click. To work this, set signalDismiss to ok or cancel in response to your
- // action- do not call Close directly or things may not work as you expect, or worse, crash.
-
- if ( signalDismiss > 0 )
- FakeClick( signalDismiss );
- }
-
-
- /*---------------------------------*** ACTIVATE ***-----------------------------------*/
- /*
- activates TextEdit if present
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::Activate()
- {
- DialogPeek dp = (DialogPeek) macWindow;
-
- if ( HasEditFields())
- TEActivate( dp->textH );
-
- inherited::Activate();
- }
-
-
- /*--------------------------------*** DEACTIVATE ***----------------------------------*/
- /*
- deactivates TextEdit if present
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::Deactivate()
- {
- inherited::Deactivate();
-
- DialogPeek dp = (DialogPeek) macWindow;
-
- if ( HasEditFields())
- TEDeactivate( dp->textH );
- }
-
-
- /*-----------------------------------*** IDLE ***-------------------------------------*/
- /*
- blink TextEdit cursor if present
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::Idle()
- {
- DialogPeek dp = (DialogPeek) macWindow;
-
- if ( HasEditFields())
- TEIdle( dp->textH );
- }
-
-
- /*-----------------------------------*** TYPE ***-------------------------------------*/
- /*
- pass TextEdit the typed character if present. If tab key, cycle through fields
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::Type( const char theKey )
- {
- DialogPeek dp = (DialogPeek) macWindow;
- short iType;
- Handle iHand;
- Rect iBox;
-
- Focus();
-
- if ( HasEditFields())
- {
- if ( theKey == TAB_KEY ) // tab
- {
- short nextField, fMax;
-
- // find the next edit field item that can be set
-
- nextField = dp->editField + 2;
- fMax = CountDITL( macWindow );
-
- do
- {
- if ( nextField > fMax )
- nextField = 1;
-
- // if we got back to where we started, so nothing. This will occur
- // if the dialog has only 1 edit field
-
- if ( nextField == dp->editField + 1 )
- return;
-
- GetDialogItem( macWindow, nextField, &iType, &iHand, &iBox );
-
- // if this is an edit field, then select that one
-
- if ( iType & editText )
- {
- SelectDialogItemText( macWindow, nextField, 0, 32767 );
- SetTEItemDataFromIctb( nextField, FALSE );
- break;
- }
-
- nextField++;
- }
- while( 1 );
- }
- else
- {
- if ( dp->textH )
- {
- ZGrafState zg;
-
- SetTEItemDataFromIctb( dp->editField + 1, TRUE );
- TEKey( theKey, dp->textH );
- }
- }
-
- ClipRect( &macWindow->portRect );
-
- // if item is enabled, call ClickItem too
-
- GetDialogItem( macWindow, dp->editField + 1, &iType, &iHand, &iBox );
-
- if (( iType & 0x80 ) == 0 )
- ClickItem( dp->editField + 1 );
- }
- }
-
-
-
- /*------------------------------*** DRAWUSERITEM ***----------------------------------*/
- /*
-
- this is called to update each user item in the dialog. You can override this to draw
- custom dialog items. The default method draws a 50% grey outline around the item.
-
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::DrawUserItem( const short item )
- {
- short itemType;
- Handle itemHand;
- Rect itemBox;
-
- GetDialogItem( macWindow, item, &itemType, &itemHand, &itemBox );
-
- // if the background of the window is not white, and the compiler flag is
- // set, draw a 3D effect line instead of a 50% gray one.
-
- #ifdef _GREYSCALE_APPEARANCE
-
- AuxWinHandle awH;
-
- if ( GetAuxWin( macWindow, &awH ))
- {
- RGBColor rc;
- GDHandle mDev;
- Rect gib;
-
- rc.red = rc.green = rc.blue = -1; // white
-
- RGBForeColor( &rc );
- OffsetRect( &itemBox, 1, 1 );
- FrameRect( &itemBox );
- OffsetRect( &itemBox, -1, -1 );
-
- gib = itemBox;
- LocalToGlobal( &topLeft( gib ));
- LocalToGlobal( &botRight( gib ));
-
- mDev = GetMaxDevice( &gib );
-
- rc.red = rc.green = rc.blue = 0; // black
- GetGray( mDev, &(*(*awH)->awCTable)->ctTable[0].rgb, &rc );
-
- RGBForeColor( &rc );
- FrameRect( &itemBox );
- }
- else
- {
- PenNormal();
- PenPat( &qd.gray );
- PenSize( 1,1 );
-
- FrameRect( &itemBox );
- }
-
- #else
-
- PenNormal();
- PenPat( &qd.gray );
- PenSize( 1,1 );
-
- FrameRect( &itemBox );
-
- #endif
-
- ForeColor( blackColor );
- PenNormal();
- }
-
-
- /*----------------------------------*** DOCUT ***-------------------------------------*/
- /*
- handle edit command cut.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::DoCut()
- {
- DialogCut( macWindow );
- gClipboard->Clear();
- FailOSErr( TEToScrap());
- }
-
-
- /*----------------------------------*** DOCOPY ***------------------------------------*/
- /*
- handle edit command copy.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::DoCopy()
- {
- DialogCopy( macWindow );
- gClipboard->Clear();
- FailOSErr( TEToScrap());
- }
-
-
- /*---------------------------------*** DOPASTE ***------------------------------------*/
- /*
- handle edit command paste.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::DoPaste()
- {
- FailOSErr( TEFromScrap());
- DialogPaste( macWindow );
- }
-
-
- /*---------------------------------*** DOCLEAR ***------------------------------------*/
- /*
- handle edit command clear.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::DoClear()
- {
- DialogDelete( macWindow );
- }
-
- /*-------------------------------*** UPDATEMENUS ***----------------------------------*/
- /*
- enable the edit menu items if we have edit fields
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::UpdateMenus()
- {
- // enable cut, copy, clear IF we have edit fields. If modal,
- // do NOT pass this on up the chain.
-
- if ( HasEditFields())
- {
- gMenuBar->EnableCommand( kCmdCut );
- gMenuBar->EnableCommand( kCmdCopy );
- gMenuBar->EnableCommand( kCmdClear );
-
- if ( CanPasteType())
- gMenuBar->EnableCommand( kCmdPaste );
- }
-
- if (! isModal)
- {
- inherited::UpdateMenus();
-
- // disable the save/save as menu item, since it is inappropriate for
- // dialogs (ancestor window may have enabled it)
-
- gMenuBar->DisableCommand( kCmdSave );
- gMenuBar->DisableCommand( kCmdSaveAs );
- }
- }
-
-
- /*-------------------------------*** CANPASTETYPE ***---------------------------------*/
- /*
- we can paste if we have edit fields and there is text on the clipboard
- ----------------------------------------------------------------------------------------*/
-
- Boolean ZDialog::CanPasteType()
- {
- return ( HasEditFields() && gClipboard->QueryType( 'TEXT' ));
- }
-
-
- /*----------------------------------*** SETUP ***-------------------------------------*/
- /*
-
- called when the dialog is built so you can initialise your dialog items. For user items,
- override DrawUserItem rather than installing your own procs here. By default, this hilites
- the text of the first edit field it finds.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::SetUp()
- {
- // set the first edit field to be hilited
-
- short i, iType, items = CountDITL( macWindow );
- Handle iHand;
- Rect iBox;
-
- for ( i = 1; i <= items; i++ )
- {
- GetDialogItem( macWindow, i, &iType, &iHand, &iBox );
-
- if (( iType & 0x7F ) == editText )
- {
- SelectDialogItemText( macWindow, i, 0, 32767 );
- break;
- }
- }
- // override this method to initialise your controls, etc to the desired
- // state for your dialog, but call the inherited method as well.
- }
-
-
- /*-----------------------------*** ADJUSTCURSOR ***-----------------------------------*/
- /*
-
- overrides ZWindow to set the cursor to an i-beam over edit fields.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::AdjustCursor( const Point mouse, const short modifiers )
- {
- short item, itemType;
- Handle itemHand;
- Rect itemBox;
- CursHandle iBeam;
-
- item = FindItem( mouse );
-
- if ( item > 0 )
- {
- GetDialogItem( macWindow, item, &itemType, &itemHand, &itemBox );
-
- if (( itemType & 0x7F ) == editText )
- {
- iBeam = GetCursor( iBeamCursor );
- SetCursor( *iBeam );
-
- return;
- }
- }
-
- inherited::AdjustCursor( mouse, modifiers );
- }
-
-
- /*--------------------------------*** CLICKITEM ***-----------------------------------*/
- /*
-
- an enabled item was clicked (or an enabled field was typed in) This handles check boxes
- by toggling their state, and OK and Cancel buttons in modal dialogs. It also now handles
- groups of radio buttons. Override to handle clicks in other dialog items, but call the
- inherited method to deal with these standard items.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::ClickItem( const short theItem )
- {
- short itemType;
- Handle itemHand;
- Rect itemBox;
- GrafPtr savePort;
-
- GetPort( &savePort );
- SetPort( macWindow );
-
- // get info about the item clicked
-
- GetDialogItem( macWindow, theItem, &itemType, &itemHand, &itemBox );
-
- // if a checkbox, toggle its state
-
- if (( itemType & 0x7F ) == ( ctrlItem + chkCtrl ))
- SetControlValue(( ControlHandle ) itemHand, GetControlValue(( ControlHandle ) itemHand ) ^ 1 );
-
- // if the item is a radio button, handle it if it is part of a group
-
- if (( itemType & 0x7F ) == ( ctrlItem + radCtrl ))
- {
- // check that the control is actually enabled
-
- if ((*( ControlHandle ) itemHand )->contrlHilite != 255 )
- HandleRButtonGroupClick( theItem );
- }
- // if it is the OK or cancel button, dismiss the dialog if a modal dialog.
-
- if ((( theItem == ok ) || ( theItem == cancel )) &&
- (( itemType & 0x7F ) == ( ctrlItem + btnCtrl )) &&
- isModal )
- {
- if ( theItem == ok )
- Close( 1 ); // verifies dialog
- else
- {
- dirty = FALSE; // suppress save check
- inherited::Close( 1 ); // does not verify dialog
-
- SendMessage( kMsgDialogCancelled, &windID );
- }
- }
-
- SetPort( savePort );
- }
-
-
- /*-------------------------------*** CLOSEDIALOG ***----------------------------------*/
- /*
-
- the dialog is about to close. You can abort the close by returning FALSE. Override to
- read the values of controls, other items, etc.
- ----------------------------------------------------------------------------------------*/
-
- Boolean ZDialog::CloseDialog()
- {
- // the dialog is about to close. Return FALSE if you can't close (Verify fields?)
-
- SendMessage( kMsgDialogSuccessfullyClosed, &windID );
-
- return TRUE;
- }
-
-
- /*----------------------------------*** CLOSE ***-------------------------------------*/
- /*
-
- overrides ZWindow so that closing the dialog correctly maintains the chain of command.
- This is called when a modeless dialog is closed from the Close menu, or go-away box, or
- when OK was clicked in a modal dialog.
- ----------------------------------------------------------------------------------------*/
-
- Boolean ZDialog::Close( short phase )
- {
- // called for a modeless dialog. This calls CloseDialog. If TRUE, the object is
- // deleted. This overrides the similar method in ZWindow.
-
- Boolean wasClosed;
-
- dirty = FALSE; // suppress save checking
-
- wasClosed = CloseDialog();
-
- if ( wasClosed )
- inherited::Close( phase );
-
- return wasClosed;
- }
-
-
- /*---------------------------------*** FILTER ***-------------------------------------*/
- /*
-
- now's your chance! This allows you to examine and modify the event that is going to come to
- this dialog before the dialog manager gets it. By default, this maps return and enter keys
- to the dialog buttons. If the event is fully handled, return TRUE, else FALSE. If TRUE is
- returned, no further processing will occur.
- ----------------------------------------------------------------------------------------*/
-
- Boolean ZDialog::Filter( EventRecord* theEvent )
- {
- char theKey;
- Boolean fullyHandled = FALSE;
- short itemType;
- Handle itemHand;
- Rect itemBox;
- Boolean cmdPeriod;
-
- // see if command-period is down
-
- cmdPeriod = ((theEvent->what == keyDown) &&
- isModal &&
- ((theEvent->modifiers & cmdKey) == cmdKey ) &&
- ((theEvent->message & charCodeMask) == '.'));
-
- // map return, enter and escape keys to ok and cancel
-
- if ((theEvent->what == keyDown) && isModal)
- {
- theKey = theEvent->message & charCodeMask;
-
- if (theKey == RETURN_KEY || // return
- theKey == ENTER_KEY) // enter
- {
- // make sure that item 1 is an enabled button
-
- GetDialogItem( macWindow, ok, &itemType, &itemHand, &itemBox );
-
- if ( itemType == ( ctrlItem + btnCtrl ))
- {
- FakeClick( ok );
- fullyHandled = TRUE;
- }
- }
-
- if (( theKey == ESCAPE_KEY ) || cmdPeriod ) // escape or command-period
- {
- // make sure item 2 is an enabled button
-
- GetDialogItem( macWindow, cancel, &itemType, &itemHand, &itemBox );
-
- if ( itemType == ( ctrlItem + btnCtrl ))
- {
- FakeClick( cancel );
- fullyHandled = TRUE;
- }
- }
- }
-
- return fullyHandled;
- }
-
-
- /*---------------------------------*** FAKECLICK ***----------------------------------*/
- /*
- fake a click on an item (presumably a button).
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::FakeClick( const short item )
- {
- long ignored;
-
- HiliteItem( item, 1 );
- Delay( 8, &ignored );
- HiliteItem( item, 0 );
-
- ClickItem( item );
- }
-
-
- /*--------------------------------*** GETITEMTYPE ***---------------------------------*/
- /*
- return the type of the item with ID passed.
- ----------------------------------------------------------------------------------------*/
-
- short ZDialog::GetItemType( const short item )
- {
- short iType;
- Handle iHand;
- Rect iRect;
-
- GetDialogItem( macWindow, item, &iType, &iHand, &iRect );
-
- return iType;
- }
-
-
- /*--------------------------------*** SETVALUE ***------------------------------------*/
- /*
-
- sets the value of the dialog item to <value>. This determines the type of the item and
- does the obvious thing. Various data types are accepted by overloading the parameters,
- though for controls, the value must be between -32767 and +32768 or an exception is thrown.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::SetValue(const short item, const long value)
- {
- short itemType;
- Handle itemHand;
- Rect itemBox;
-
- GetDialogItem( macWindow, item, &itemType, &itemHand, &itemBox );
-
- // for controls: check that parameter is within range, then set the control value
-
- if (( itemType & ctrlItem ) == ctrlItem )
- {
- if ( value < -32767 || value > 32768 )
- FailOSErr( paramErr );
- else
- SetControlValue(( ControlHandle ) itemHand, value );
- }
- else
- {
- // for text items: convert long to string, and set item text
-
- if ( itemType & ( editText | statText ))
- {
- Str255 iText;
-
- NumToString( value, iText );
- SetDialogItemText( itemHand, iText );
- }
- }
- }
-
-
- /*--------------------------------*** SETVALUE ***------------------------------------*/
-
- void ZDialog::SetValue( const short item, const Str255 value )
- {
- short itemType;
- Handle itemHand;
- Rect itemBox;
-
- GetDialogItem( macWindow, item, &itemType, &itemHand, &itemBox );
-
- if ( itemType & ( editText | statText ))
- SetDialogItemText( itemHand, value );
- }
-
-
- /*--------------------------------*** SETVALUE ***------------------------------------*/
-
- void ZDialog::SetValue( const short item, const double value )
- {
- short itemType;
- Handle itemHand;
- Rect itemBox;
-
- GetDialogItem( macWindow, item, &itemType, &itemHand, &itemBox );
-
- if (( itemType & ctrlItem ) == ctrlItem )
- {
- SetValue( item, (long) value );
- }
- else
- {
- if ( itemType & ( editText | statText ))
- {
- Str255 iText;
-
- RealToString( value, iText );
- SetDialogItemText( itemHand, iText );
- }
- }
- }
-
- /*--------------------------------*** GETVALUE ***------------------------------------*/
- /*
-
- gets the value of the dialog item. This determines the type of the item and
- does the obvious thing. For unknown items, returns 0.
- ----------------------------------------------------------------------------------------*/
-
- long ZDialog::GetValue( const short item )
- {
- short itemType;
- Handle itemHand;
- Rect itemBox;
-
- GetDialogItem( macWindow, item, &itemType, &itemHand, &itemBox );
-
- if (( itemType & ctrlItem ) == ctrlItem )
- return GetControlValue(( ControlHandle ) itemHand );
-
- if (( itemType & editText ) == editText )
- {
- long value;
- Str255 iText;
-
- GetDialogItemText( itemHand, iText );
- StringToNum( iText, &value );
-
- return value;
- }
-
- return 0;
- }
-
-
- /*-----------------------------*** GETVALUEASTEXT ***---------------------------------*/
- /*
- get text of item, or if control, convert value to string first (complementary function to
- GetValue().
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::GetValueAsText( const short item, Str255 aStr )
- {
- short iType;
- Handle iHand;
- Rect iBox;
-
- GetDialogItem( macWindow, item, &iType, &iHand, &iBox );
-
- if ( iType & ( statText | editText ))
- GetDialogItemText( iHand, aStr );
- else
- {
- if ( iType & ctrlItem )
- {
- long v = GetValue( item );
-
- NumToString( v, aStr );
- }
- }
- }
-
-
- float ZDialog::GetValueAsFloat( const short item )
- {
- Str255 itxt;
- decimal d;
- short vp, ix = 1;
-
- GetValueAsText( item, itxt );
-
- // make sure it can be read as a null-terminated string
-
- itxt[itxt[0] + 1 ] = 0;
-
- str2dec((const char*) itxt, &ix, &d, &vp);
- return dec2f( &d );
- }
-
-
- /*-----------------------------*** GETITEMBOUNDS ***----------------------------------*/
- /*
- get rect of item
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::GetItemBounds( const short item, Rect* bounds )
- {
- short iType;
- Handle iHand;
-
- GetDialogItem( macWindow, item, &iType, &iHand, bounds );
- }
-
-
- /*--------------------------------*** FINDITEM ***------------------------------------*/
- /*
- find the item under the mouse point (local coordinates), 0 if no item there
- ----------------------------------------------------------------------------------------*/
-
- short ZDialog::FindItem( const Point localMouse )
- {
- return ( FindDialogItem( macWindow, localMouse ) + 1);
- }
-
-
- /*------------------------------*** HILITEITEM ***------------------------------------*/
- /*
- allows controls to be hilited or dimmed
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::HiliteItem(const short item, const short state)
- {
- short itemType;
- Handle itemHand;
- Rect itemBox;
-
- GetDialogItem( macWindow, item, &itemType, &itemHand, &itemBox );
-
- if (( itemType & ctrlItem ) == ctrlItem )
- HiliteControl(( ControlHandle ) itemHand, state );
- }
-
-
- /*--------------------------*** OUTLINEDEFAULTITEM ***--------------------------------*/
- /*
- draws the bold border around the item number 1 in the dialog
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::OutlineDefaultItem()
- {
- short itemType;
- Handle itemHand;
- Rect itemBox;
-
- GetDialogItem( macWindow, ok, &itemType, &itemHand, &itemBox );
-
- // check that this item is a button
-
- if ( itemType & ( ctrlItem + btnCtrl ))
- {
- Focus();
- PenSize( 3, 3 );
- InsetRect( &itemBox, -4, -4 );
- PenMode( patOr );
- ForeColor( blackColor );
-
- // if button disabled, draw the outline in grey (50% pat on B/W macs)
-
- if ((*(ControlHandle) itemHand)->contrlHilite != 0 )
- {
- if ( gMacInfo.supportsColour )
- {
- RGBColor aGray = { 0x7F7F, 0x7F7F, 0x7F7F };
-
- RGBForeColor( &aGray );
- }
- else
- PenPat( &qd.gray );
- }
- FrameRoundRect( &itemBox, 16, 16 );
- PenNormal();
- ForeColor( blackColor );
- }
- }
-
-
- /*-----------------------------*** HASEDITFIELDS ***----------------------------------*/
- /*
-
- returns TRUE if this dialog has any edit fields. Used to determine if Edit commands are
- enabled or not.
-
- ----------------------------------------------------------------------------------------*/
-
- Boolean ZDialog::HasEditFields()
- {
- // returns TRUE if this dialog has at least one edit field. Use to enable
- // the edit menu.
-
- short itemType, item;
- Handle itemHand;
- Rect itemBox;
- Boolean hasEF = FALSE;
-
- item = CountDITL( macWindow );
-
- while(item)
- {
- GetDialogItem( macWindow, item--, &itemType, &itemHand, &itemBox );
-
- if (( itemType & 0x7F ) == editText &&
- ( itemBox.left < 16384 ))
- {
- hasEF = TRUE;
- break;
- }
- }
-
- return hasEF;
- }
-
-
- /*-----------------------------*** SETUPRADIOGROUPS ***-------------------------------*/
- /*
- This builds the array of radio button groups so that the click handler can correctly
- manage them. This is done very easily- in your DITL resource, add the group ID to the
- button title, separated by a double slash- e.g. My Button//1. This function strips the
- extra characters from the name, so you never see them. Groups start at ID = 1, and
- obviously buttons with the same group ID operate as a set. If you do not extend the title
- of a group button in this way, it will operate in the normal way- i.e. not very well.
-
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::SetUpRadioGroups()
- {
- short iType, tIndex, groupID;
- Boolean iDefault;
- Handle iHand;
- Rect iBox;
- long tSize;
- Str255 cTitle;
-
- short iCount = CountDITL( macWindow );
-
- do
- {
- GetDialogItem( macWindow, iCount, &iType, &iHand, &iBox );
-
- // is this item a radio button?
-
- if ((iType & ( radCtrl + ctrlItem )) == ( radCtrl + ctrlItem ))
- {
- // yes, so make an entry for it in the group table. Note that all radio
- // buttons get an entry- those that do not take advantage of this scheme
- // have a groupID of zero, which instructs HandleRButtonGroupClick() to
- // ignore the button.
-
- tSize = GetHandleSize((Handle) rGroupList );
- tIndex = tSize / sizeof( RGroupEntry );
-
- SetHandleSize((Handle) rGroupList, tSize + sizeof( RGroupEntry ));
-
- // get the title of the button
-
- GetControlTitle((ControlHandle) iHand, cTitle );
-
- // parse the title looking for a double slash followed by a number. This
- // is returned in groupID, and the title is stripped of the extra chars.
-
- ParseRButtonTitle( cTitle, &groupID, &iDefault );
-
- // set up the entry in the table
-
- (*rGroupList)[tIndex].item = iCount;
- (*rGroupList)[tIndex].groupID = groupID;
-
- // set the button's name to eliminate the grouping info
-
- SetControlTitle((ControlHandle) iHand, cTitle );
-
- // if this is the default button, set it ON
-
- if ( iDefault )
- SetControlValue((ControlHandle) iHand, 1 );
- }
- }
- while( --iCount );
- }
-
-
- /*---------------------------*** PARSERBUTTONTITLE ***--------------------------------*/
- /*
- Finds any group ID "buried" in the button name. This modifies the input string so that
- the extra characters are removed.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::ParseRButtonTitle( Str255 buttonTitle, short* groupID, Boolean* isDefault )
- {
- register char cc = 1;
- long gID = 0;
- Str15 subStr;
-
- *groupID = 0; // in case we find nothing at all
- *isDefault = FALSE;
-
- // scan the string looking for two consecutive forward slashes:
-
- do
- {
- if ((buttonTitle[cc] == '/') && (buttonTitle[cc + 1] == '/'))
- {
- // found two consecutive slashes- now copy the rest of the string into
- // subStr.
-
- subStr[0] = buttonTitle[0] - cc - 1; // length of remainder of string
- if (subStr[0])
- {
- BlockMoveData(&buttonTitle[cc + 2], &subStr[1], subStr[0]);
-
- // look to see if this is the default button in the group. This is indicated
- // by the ID number being followed by a '*' character.
-
- if ( subStr[subStr[0]] == '*' )
- {
- *isDefault = TRUE;
-
- // remove char from string
-
- subStr[0]--;
- }
- else
- *isDefault = FALSE;
-
- // convert substring to a number. Note that results are unpredictable if
- // the string does not have a pure number following the two slashes.
- // e.g. "My Button//hello" will certainly not work!
-
- StringToNum( subStr, &gID );
-
- // shorten original string by the amount needed to remove extra
-
- buttonTitle[0] = cc - 1;
- *groupID = LoWord( gID );
-
- break;
- }
- }
- }
- while( ++cc <= buttonTitle[0] );
- }
-
-
- /*------------------------*** HANDLERBUTTONGROUPCLICK ***-----------------------------*/
- /*
- turns off the buttons in the same group as this item, then turns this one on.
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::HandleRButtonGroupClick(const short item)
- {
- // <item> is already known to be a radio button, so find its "groupies" and turn them
- // all off. Then turn this one on.
-
- short groupID, tIndex, gIndex, offItem;
-
- // search the group table for this item.
- // How many entries in the table?
-
- gIndex = tIndex = GetHandleSize((Handle) rGroupList) / sizeof(RGroupEntry);
-
- // for each item in the table, see if it is this item...
-
- while( tIndex )
- {
- if ((*rGroupList)[--tIndex].item == item )
- {
- // found this item- what is its group ID?
-
- groupID = (*rGroupList)[tIndex].groupID;
-
- if ( groupID != 0 )
- {
- // found the group ID and it is not zero (meaning do not handle)
- // now we need to find all the other items in this group and turn them off
-
- while( gIndex )
- {
- if ((*rGroupList)[--gIndex].groupID == groupID )
- {
- offItem = (*rGroupList)[gIndex].item;
- SetValue( offItem, 0 );
- }
- }
-
- // now turn on the desired item
-
- SetValue( item, 1 );
- }
- // this item is now fully handled, so don't bother searching any further.
-
- break;
- }
- }
- }
-
-
- /*-------------------------*** SETTEITEMDATAFROMICTB ***------------------------------*/
- /*
- sets the TextEdit record that is handling the item to the relevant parameters in the
- associated 'ictb' resource. We made a copy of this resource when the dialog was opened.
- WARNING: ensure that the item is an edit text field before calling this!
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::SetTEItemDataFromIctb( const short teItem, Boolean applyChanges )
- {
- if ( ictb )
- {
- // there is an ictb, so see if this item has a special entry:
-
- TEHandle te;
- ictbItemEntry ie;
- TextStyle tsRec;
-
- te = ((DialogPeek) macWindow)->textH;
- ie = (*ictb)[ teItem - 1 ];
-
- if ( ie.iData != 0 &&
- ie.iOffset != 0 )
- {
- // yes, there is a special setting for this item- what is it?
-
- ictbTablePtr tp;
-
- tp = ( ictbTablePtr ) ((Ptr) *ictb + ie.iOffset );
-
- // tp is now pointing at the text table for the item. Using this table,
- // we need to set up a TEStyle record and pass it to TextEdit.
-
- // the font is either already known or can be looked up via its name
-
- if ( ie.iData & fFamChange )
- {
- if ( ie.iData & fIsFNameOffset )
- {
- // need to look up the font via the name table. In this case
- // txtFont contains the offset to the font's name
-
- GetFNum((unsigned char*) *ictb + tp->txtFont , &tsRec.tsFont);
- }
- else
- tsRec.tsFont = tp->txtFont;
- }
- else
- tsRec.tsFont = 0;
-
- // set simple fields
-
- if ( ie.iData & fFaceChange )
- tsRec.tsFace = tp->txtFace;
- else
- tsRec.tsFace = 0;
-
- if ( ie.iData & fSizeChange )
- tsRec.tsSize = tp->txtSize;
- else
- tsRec.tsSize = 0;
-
- // set the colours of the port
-
- if ( applyChanges )
- {
- if ( ie.iData & fFColourChange )
- RGBForeColor( &tp->txtFColour );
-
- if ( ie.iData & fBColourChange )
- RGBBackColor( &tp->txtBColour );
- }
- }
- else
- tsRec.tsFace = tsRec.tsFont = tsRec.tsSize = 0;
-
- (*te)->txFont = tsRec.tsFont;
- (*te)->txFace = tsRec.tsFace;
- (*te)->txSize = tsRec.tsSize;
-
- // note: at this point, the lineHeight of the teRec should be calculated for the new
- // font. However, the dialog manager doesn't do this (it should). To be compatible, we
- // don't set this either. If all your fields use the same, but non-standard font, it
- // is recommended that you get the lineHeight and ascent and set up the dialog's teRec
- // correctly in the SetUp() method.
- }
- }
-
-
- /*--------------------------*** ADDGREYSCALEEFFECTS ***-------------------------------*/
- /*
- adds 3D effect borders to edit text items
- ----------------------------------------------------------------------------------------*/
-
- void ZDialog::AddGreyscaleEffects()
- {
- short n, iType;
- Handle iHand;
- Rect r;
-
- n = CountDITL( macWindow );
-
- while( n )
- {
- GetDialogItem( macWindow, n--, &iType, &iHand, &r );
-
- if (( iType & 0x7F ) == editText )
- {
- InsetRect( &r, -3, -3 );
- FrameGrayRect( &r );
- }
- }
- }
-
-
- #pragma mark -
- /*--------------------------*** UserItemVectorProc ***--------------------------------*/
- /*
-
- This is used to vector user-item updates to the DrawUserItem method. Do not change this-
- override DrawUserItem instead.
-
- ----------------------------------------------------------------------------------------*/
-
- static pascal void UserItemVectorProc( DialogPtr theDialog, short item )
- {
- ZDialog* aZD = (ZDialog*) GetWRefCon( theDialog );
-
- if ( aZD )
- aZD->DrawUserItem( item );
- }
-
-
- /*-------------------------------*** REALTOSTRING ***---------------------------------*/
-
- void RealToString( const double num, Str255& str )
- {
- // first, stuff the integer part
- NumToString( num, str );
- // now, stuff the decimal point...
- str[++str[0]] = '.';
- // finally, stuff the stuff past the decimal...
- // since we need this to be zero-padded, we can't use NumToString here
- int v= 1000*(double)(num > 0 ? num-(int)num : (int)num - num);
- for (int i=3; i>0; i--) {
- str[str[0]+i] = '0' + v%10;
- v /= 10;
- }
- str[0] += 3;
- // add a lost negative sign -- occurs when int part is 0
- if (num < 0 && num > -1)
- {
- BlockMove( str+1, str+2, str[0] ); // shift everything over
- str[1] = '-'; // add negative sign
- str[0]++; // increase string length
- }
- }
-
-
- /*-------------------------------*** FRAMEGRAYRECT ***---------------------------------*/
-
-
- void FrameGrayRect( Rect* aRect )
- {
- GDHandle aDev;
- RGBColor aColour = { -1, -1, -1 };
- RGBColor bColour = { 0, 0, 0 };
-
- // frames a rectangle using two shades of gray so that the rectangle appears to
- // be recessed into a gray surface. This actually draws 1 pixel outside the
- // passed rectangle, so that normal FrameRect calls work as expected in addition.
-
- RGBForeColor( &aColour );
- MoveTo( aRect->left, aRect->bottom );
- LineTo( aRect->right, aRect->bottom );
- LineTo( aRect->right, aRect->top );
-
- aDev = GetMaxDevice( aRect );
-
- GetGray( aDev, &aColour, &bColour );
- RGBForeColor( &bColour );
-
- Move( 0, -1 );
- LineTo( aRect->left - 1, aRect->top - 1 );
- LineTo( aRect->left - 1, aRect->bottom );
-
- ForeColor( blackColor );
- }
-
-
-
-